local Msg = require("core.Msg")
local Grid = require("bag.Grid")
local FamilyWarReward = require("excel.FamilyWar").WarReward[1]
local FamilyManager = require("family.FamilyManager")
local Broadcast = require("broadcast.Broadcast")
local Lang = require("common.Lang")
local FamilyDefine = require("family.FamilyDefine")
local MPacketDefine = require("middle.MPacketDefine")
local Config = require("Config")
local LuaMongo = _G.lua_mongo
local DB = require("common.DB")
local Human = require("core.Human")
local ServerCommon = require("serverCommon.ServerCommonFW")
local MiddleLogic = require("middle.MiddleLogic")
local MiddleOpenDB = require("middle.MiddleOpenDB")
local InnerDataManagerFW = require("innerdata.InnerDataManagerFW")
local InnerDefine = require("innerdata.Define")
local CopyDefine = require("copy.Define")
local Copy = require("copy.CopyW")
local MailLogicFW = require("mail.MailLogicFW")
local FamilyLogicFW = require("family.FamilyLogicFW")
local RoleDBLogic = require("role.RoleDBLogic")
local Log = require("common.Log")


TIME_TYPE_SIGN = 0  --报名时间（周一到周四）
TIME_TYPE_READY = 1 --准备时间（周五20：00前）
TIME_TYPE_ROUND1 = 2 --第一轮战斗（周五20：00-20：20）
TIME_TYPE_ROUND1END = 3--第一轮战斗结束（周五20：20-20：59）
TIME_TYPE_ROUND2 = 4 --第二轮战斗 （周五21：00-21:20）
TIME_TYPE_ROUND2END = 5--第二轮战斗结束（周五21：20-周六20:00）
TIME_TYPE_ROUND3 = 6 --第三轮战斗 （周六20：00-20:20）
TIME_TYPE_ROUND3END = 7--第三轮战斗结束（周六20：20 到 20:59）
TIME_TYPE_ROUND4 = 8 --第四轮战斗(周六21:00-21:20)
TIME_TYPE_ROUND4END = 9 -- 第四轮战斗结束（周六21:20-周一00：00)

FAMILY_STATUS_NOSIGN = 0   -- 未报名
FAMILY_STATUS_SIGN = 1     -- 已报名
FAMILY_STATUS_COMBAT = 2   -- 争霸中
FAMILY_STATUS_FAIL = 3     -- 落选


FAMILY_WAR_SIGN_DATA = FAMILY_WAR_SIGN_DATA or nil   -- uuid-> {uuid, name, 0}
FAMILY_WAR_DATA = FAMILY_WAR_DATA or nil   -- rank ->{uuid, name, rank}
familyWarStatus = familyWarStatus or 0 -- 状态
familyWarStatus_db = familyWarStatus_db or {} 

familyStartTime = familyStartTime or nil --开始时间
familyEndTime = familyEndTime or nil --结束时间
familyCopyRoom = familyCopyRoom or {} -- familyUuid -> roomID
_gmCheckTime = _gmCheckTime or nil

prefixName = "["..Config.SVR_INDEX%100000 .."]"
local ROUND_RANK = {{16,31},{8,15},{4,7},{2,3}}

AssertFix = {}

finish4RoundTime = finish4RoundTime or nil   --多长时间后logic线程没有返回结果，直接计算

function init()
    if not Config.IS_MIDDLE then      
      return
    end
    LuaMongo.find(DB.db_middleFamilyWar)  
    FAMILY_WAR_SIGN_DATA = {}
    FAMILY_WAR_DATA = {}
    while true do 
      local familyData = {}
      if not LuaMongo.next(familyData) then
          break
      end
      if familyData.rank == 0 or familyData.rank == 101 then
          FAMILY_WAR_SIGN_DATA[familyData.uuid] = familyData
      else
          FAMILY_WAR_DATA[familyData.rank] = familyData
      end
    end
    LuaMongo.find(DB.db_middleFamilyWarStatus)
    if not LuaMongo.next(familyWarStatus_db) then
        LuaMongo.insert(DB.db_middleFamilyWarStatus,familyWarStatus_db)
    end

    familyWarStatus = checkTime()
    
    if familyWarStatus_db.status and familyWarStatus_db.status ~= familyWarStatus then --处理程序异常崩溃问题
        --状态检测
          assertFix(familyWarStatus_db.status, familyWarStatus)
    end   
    saveWarStatus() 
end
local DBStatusUpdate = {}
function saveWarStatus()
    familyWarStatus_db.status = familyWarStatus
    DBStatusUpdate._id = familyWarStatus_db._id
    LuaMongo.update(DB.db_middleFamilyWarStatus,DBStatusUpdate,familyWarStatus_db)
end

function assertFix(oldStatus, newStatus)
    for i = 1, 9 do
        local s = (oldStatus + i)%8 
        if AssertFix[s] then
           print("s:", s)
           AssertFix[s]()
        end
        if s == newStatus then
            break
        end
    end
end

function insert(data)
    data._id = nil
    LuaMongo.insert(DB.db_middleFamilyWar, data)
end
local QueryUpdate = {}
function update(data)
    QueryUpdate._id = data._id
    LuaMongo.update(DB.db_middleFamilyWar, QueryUpdate, data)
end
function remove(data)
    if data then
      QueryUpdate._id = data._id
      LuaMongo.remove(DB.db_middleFamilyWar, QueryUpdate)
    end
end


local function newData(familyUuid, familyName,svrIndex)
     return {
            uuid = familyUuid,
            name = familyName,            
            rank = 0, -- 0报名，  1 为霸主， 2-3， 4-5-6-7， 8-9-10-11-12-13-14-15, 100为上届霸主101为参战数据
            time = os.time(),
            svrIndex = svrIndex,
            zhandouli = 0,
            leaderUuid = "",
            leaderName ="",
            leaderFuUuid="",
            leaderFuName="",
            win = 0, -- 0-未决出胜负，1胜,2败
      }
end

local function cloneData(src)
     local ret = {}
     for k,v in pairs(src) do
        ret[k] = v
     end
     return ret
end
DATA_TYPE_CAN_WAR = 0   --参战数据
DATA_TYPE_ROUND1 = 1    --第一轮对战数据
DATA_TYPE_ROUND2 = 2    --第二轮对战数据
DATA_TYPE_ROUND3 = 3    --第三轮对战数据
DATA_TYPE_ROUND4 = 4    --第四轮对战数据
DATA_TYPE_WIN    = 5    --霸主
DATA_TYPE_LAST_WIN=6    --上届霸主

local function getData(t)    -- t如上
     if t == DATA_TYPE_CAN_WAR then
        return FAMILY_WAR_SIGN_DATA
     end
     local d = {}
     if t == DATA_TYPE_ROUND1 then
        for i = 16, 31 do
            if FAMILY_WAR_DATA[i] then
                d[#d+1] = FAMILY_WAR_DATA[i]
            else
                d[#d+1] = {name="", rank=i} 
            end
        end
     elseif t == DATA_TYPE_ROUND2 then
        for i = 8,15 do
            if FAMILY_WAR_DATA[i] then
                d[#d+1] = FAMILY_WAR_DATA[i]
            else
                d[#d+1] = {name="", rank=i} 
            end
        end
     elseif t == DATA_TYPE_ROUND3 then
        for i = 4,7 do
            if FAMILY_WAR_DATA[i] then
                d[#d+1] = FAMILY_WAR_DATA[i]
            else
                d[#d+1] = {name="", rank=i} 
            end
        end
     elseif t == DATA_TYPE_ROUND4 then
        for i = 2,3 do
            if FAMILY_WAR_DATA[i] then
                d[#d+1] = FAMILY_WAR_DATA[i]
            else
                d[#d+1] = {name="", rank=i} 
            end
        end        
     elseif t == DATA_TYPE_WIN then
        d[1] = FAMILY_WAR_DATA[1]
        if not d[1] then
            d[1] = {name="", rank=1} 
        end
        print("print:", d[1].name,FAMILY_WAR_DATA[1])
     elseif t == DATA_TYPE_LAST_WIN then
        d[1] = FAMILY_WAR_DATA[100]
     end
     return d
end



--检查当前时间断
function checkTime()
    if _gmCheckTime then
        return _gmCheckTime
    end
    local t = os.time()
    local d = os.date("*t",t)
    if d.wday > 1 and d.wday < 6 then
        return TIME_TYPE_SIGN
    end 
    if d.wday == 6 then
        if d.hour < 20 then
            return TIME_TYPE_READY
        end
        if d.hour < 21 then
            if d.min <= 20 then
                return TIME_TYPE_ROUND1
            else
                return TIME_TYPE_ROUND1END
            end
        end
        if d.hour == 21 and d.min <=20 then
            return TIME_TYPE_ROUND2
        end
        return TIME_TYPE_ROUND2END
    end
    if d.wday == 7 then
        if d.hour < 20 then
            return TIME_TYPE_ROUND2END
        end
        if d.hour == 20 then
            if d.min <=20 then
                return TIME_TYPE_ROUND3
            else
                return TIME_TYPE_ROUND3END
            end
        end
        if d.hour == 21 and d.min <= 20 then
            return TIME_TYPE_ROUND4
        end 
    end
    return TIME_TYPE_ROUND4END   
end
function gmCheckTime(v)
    if v <= 9 then
      _gmCheckTime = v
    end
    print("_gmCheckTime:", familyWarStatus,v)
    if v >= 10 then
       local newStatus = v%10
       if newStatus ~= familyWarStatus then
          assertFix(familyWarStatus, newStatus)
       end
       _gmCheckTime = newStatus
       familyWarStatus = newStatus       
       syncFamilyWarData()
	     saveWarStatus()
       print("........fuck:", familyWarStatus, newStatus)
    end
end
function checkMiddleOpen()
    if Config.IS_MIDDLE then return true end
    if not MiddleLogic.ENABLE_MIDDLE then
        return
    end
    if not MiddleOpenDB.isMiddleOpen() then
        return
    end
    if _G.msg_middle_parse.check_connect() ~= true then 
        return
    end
    return true
end

function checkCanEnterMiddle(human) 
    if Config.IS_MIDDLE then
        local roomID = familyCopyRoom[human.familyUuidM]
        if not roomID or not Copy.roomDatas[CopyDefine.COPY_FAMILYWAR_ID] 
            or not Copy.roomDatas[CopyDefine.COPY_FAMILYWAR_ID][roomID]
            or Copy.roomDatas[CopyDefine.COPY_FAMILYWAR_ID][roomID].finishCode then
            return ""
        end
        return 
    end
    --正常服
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_NOT_EXIST)    
        return Lang.FAMILY_NOT_EXIST
    end
    local member = FamilyManager.getMember(family, human._id)
    if not member then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_NOT_EXIST)
        return Lang.FAMILY_NOT_EXIST
    end
    if family.middleFamilyWarStatus ~= FAMILY_STATUS_COMBAT then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_NO_START)
        return Lang.FAMILY_WAR_NO_START
    end
    
    if not isWarTime() then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_NO_START)
        return Lang.FAMILY_WAR_NO_START
    end
    
    if not family.middleFamilyCanEnter then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_NO_WAR)
        return Lang.FAMILY_WAR_NO_WAR
    end
    if not member.fwar then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_NO_JOIN)
        return Lang.FAMILY_WAR_NO_JOIN
    end
end

-------------游戏服逻辑---------------------
function isWarTime()
  return familyWarStatus == TIME_TYPE_ROUND1 or familyWarStatus == TIME_TYPE_ROUND2 or familyWarStatus == TIME_TYPE_ROUND3 or familyWarStatus == TIME_TYPE_ROUND4
end

function isFamilyWaring(uuid)
    local family = FamilyManager.findByUuid(uuid)
    if not family or family.middleFamilyWarStatus ~= FAMILY_STATUS_COMBAT then
        return
    end
    if not FAMILY_WAR_DATA then
        return
    end
    local r = 0
    if familyWarStatus == TIME_TYPE_READY or familyWarStatus == TIME_TYPE_ROUND1 then
        r = 1
    elseif familyWarStatus == TIME_TYPE_ROUND1END or familyWarStatus == TIME_TYPE_ROUND2 then
        r = 2
    elseif familyWarStatus == TIME_TYPE_ROUND2END or familyWarStatus == TIME_TYPE_ROUND3 then
        r = 3
    elseif familyWarStatus == TIME_TYPE_ROUND3END or familyWarStatus == TIME_TYPE_ROUND4 then
        r = 4
    else
        return
    end
    for i = ROUND_RANK[r][1], ROUND_RANK[r][2] do
        if FAMILY_WAR_DATA[i] and FAMILY_WAR_DATA[i].uuid == family._id then
            return true
        end
    end    
    return 
end

REWARD_CACHE = nil
function rewardQuery(human)
    local msg = Msg.gc.GC_FAMILY_WAR_REWARD_QUERY
    if not REWARD_CACHE then
        for i = 1, 4 do
            local reward = FamilyWarReward.warReward[i]
            if not reward then
                break
            end
            local grid = {}
            Grid.create(grid, reward[1], reward[2], reward[3])            
            Grid.makeItem(grid, msg.reward1[i])
            msg.reward1[0] = i
        end
        for i = 1, 4 do
            local reward = FamilyWarReward.winLeaderReward[i]
            if not reward then
                break
            end
            local grid = {}
            Grid.create(grid, reward[1], reward[2], reward[3])            
            Grid.makeItem(grid, msg.reward2[i])
            msg.reward2[0] = i
        end
        for i = 1, 4 do
            local reward = FamilyWarReward.winMemberReward[i]
            if not reward then
                break
            end
            local grid = {}
            Grid.create(grid, reward[1], reward[2], reward[3])            
            Grid.makeItem(grid, msg.reward3[i])
            msg.reward3[0] = i
        end
    end
    Msg.send(msg, human.fd)
end

realRewardCache = {}
rewardKey = {"round1WinReward","round1FailReward","round2WinReward","round2FailReward","round3WinReward", "round3FailReward", "round4WinReward", "round4FailReward"}
local function getReward(round, win, member)
    local k = rewardKey[(round-1)*2+ (win and 1 or 2)]
    if member then
        k = "round4WinMember"
    end
    if not k then return end
    if not realRewardCache[k] then
        realRewardCache[k] = {}
        local grid
        local conf
        for i = 1, #FamilyWarReward[k] do
            grid = {}
            conf = FamilyWarReward[k][i]
            Grid.create(grid, conf[1], conf[2], conf[3])
            realRewardCache[k][i] = grid
        end
    end
    return realRewardCache[k]
end

local function sendFamilyWarDataWQuery(human)
    _G.msg_middle_parse.writebegin(0)
    _G.msg_middle_parse.writeint(MPacketDefine.G2M_FAMILY_WAR_LIST)
    _G.msg_middle_parse.writeend()  
end

function sendFamilyData(family)
    if not checkMiddleOpen() or (family.middleFamilyWarStatus ~= FAMILY_STATUS_SIGN and family.middleFamilyWarStatus ~= FAMILY_STATUS_COMBAT)  then
        return
    end
        _G.msg_middle_parse.writebegin(0)
        _G.msg_middle_parse.writeint(MPacketDefine.G2M_FAMILY_DATA)
        _G.msg_middle_parse.writestring(family._id)        
        _G.msg_middle_parse.writeint(FamilyManager.getZhandouli(family))
        local leader = FamilyManager.getLeader(family)
        _G.msg_middle_parse.writestring(leader.uuid)
        local leaderUuid = leader.uuid
        _G.msg_middle_parse.writestring(prefixName..leader.name)
        leader = FamilyManager.getMemberByOfficial(family,FamilyDefine.OFFICIAL_FU_LEADER)
        if leader then
            _G.msg_middle_parse.writestring(leader.uuid)
            _G.msg_middle_parse.writestring(prefixName..leader.name)
        else
            _G.msg_middle_parse.writestring("")
            _G.msg_middle_parse.writestring("")
        end    
        _G.msg_middle_parse.writeend()      
end
function signQuery(human)
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_NOT_EXIST)    
        return
    end
    local member = FamilyManager.getMember(family, human._id)
    if not member then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_NOT_EXIST)
        return 
    end
    local msg = Msg.gc.GC_FAMILY_WAR_SIGN_QUERY
    msg.lastWin[0] = 0 
    msg.enightData[0] = 0
    msg.firstRound[0] = 0
    msg.secondRound[0] = 0
    msg.thirdRound[0] = 0
    msg.fourRound[0] = 0
    msg.winData[0] = 0
    msg.status = 0
    msg.type = 0
    if not checkMiddleOpen() then
        Msg.send(msg, human.fd) 
        return    
    end
    
    if not FAMILY_WAR_SIGN_DATA then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_WEIHU)  
        Msg.send(msg, human.fd) 
        sendFamilyWarDataWQuery()
        return        
    end 
    
--    local d = getData(DATA_TYPE_CAN_WAR)
--    local len = #d
--    if len > 8 then len = 8 end
--    for i = 1, len do
--        msg.enightData[i].name = d[i].name
--        msg.enightData[i].pos = d[i].rank
--    end
    msg.enightData[0] = 0
    
    local d = getData(DATA_TYPE_ROUND1)
    local len = #d
    if len > 16 then len = 16 end
    for i = 1, len do
        msg.firstRound[i].name = d[i].name
        msg.firstRound[i].pos = d[i].rank
    end
    msg.firstRound[0] = len
   
    d = getData(DATA_TYPE_ROUND2)
    len = #d
    if len > 8 then len = 8 end
    for i = 1, len do
        msg.secondRound[i].name = d[i].name
        msg.secondRound[i].pos = d[i].rank        
    end
    msg.secondRound[0] = len 
    
    d = getData(DATA_TYPE_ROUND3)
    len = #d
    if len > 4 then len = 4 end
    for i = 1, len do
        msg.thirdRound[i].name = d[i].name
        msg.thirdRound[i].pos = d[i].rank
    end
    msg.thirdRound[0] = len
    
    d = getData(DATA_TYPE_ROUND4)
    len = #d
    if len > 2 then len = 2 end
    for i = 1, len do
        msg.fourRound[i].name = d[i].name
        msg.fourRound[i].pos = d[i].rank
        print("name:", d[i].name, d[i].rank)
    end
    msg.fourRound[0] = len
    
    
    d = getData(DATA_TYPE_WIN)
    if d[1] then
        msg.winData[1].name = d[1].name
        msg.winData[1].pos  =  d[1].rank
        msg.winData[0] = 1       
    end
    
    d = getData(DATA_TYPE_LAST_WIN)
    if d[1] then
        msg.lastWin[1].name = d[1].name
        msg.lastWin[1].pos = d[1].rank
        msg.lastWin[0] = 1
    end
    msg.type = familyWarStatus
    msg.status = family.middleFamilyWarStatus
    
    print("msg.status:", family.middleFamilyWarStatus, familyWarStatus)
    Msg.send(msg, human.fd)
end

function sign(human)
    if not checkMiddleOpen() then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_WEIHU)    
        return    
    end
    local family = FamilyManager.findByUuid(human.familyUuid)
    if not family then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_NOT_EXIST)    
        return
    end
    local member = FamilyManager.getMember(family, human._id)
    if not member then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_NOT_EXIST)
        return 
    end
    if family.middleFamilyWarStatus >1 then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_NOT_SIGN)
        return
    end
    if family.middleFamilyWarStatus == 1 then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_HAD_SIGN)
        return
    end
    if family.familyLv < 2 then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_NO_LV)
        return
    end
    if member.official ~= FamilyDefine.OFFICIAL_LEADER and member.official ~= FamilyDefine.OFFICIAL_FU_LEADER then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_NO_OFFICE)
        return    
    end
    if familyWarStatus~= TIME_TYPE_SIGN then
        Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_NOT_SIGN)
        return
    end
    _G.msg_middle_parse.writebegin(0)
    _G.msg_middle_parse.writeint(MPacketDefine.G2M_FAMILY_WAR_SIGN)
    _G.msg_middle_parse.writeint(Config.SVR_INDEX)  
    _G.msg_middle_parse.writestring(family._id)
    _G.msg_middle_parse.writestring(prefixName..family.familyName)
    _G.msg_middle_parse.writestring(human._id)
    _G.msg_middle_parse.writeend()   
    
    
end


function M2G_FAMILY_WAR_SIGN(fd, msg)
    local family = FamilyManager.findByUuid(msg.familyUuid)
    if not family then
        return
    end
    print("M2G_FAMILY_WAR_SIGN2:")
    family.middleFamilyWarStatus = FAMILY_STATUS_SIGN
    FamilyManager.update(family)
    sendFamilyData(family)    --发送军团数据 
    local member =  FamilyManager.getMember(family, msg.uuid)
    if not member then
        return
    end
    local human = Human.onlineUuid[msg.uuid]
    if not human or not human.fd then
        return
    end
     
    local f  
    for k, v in ipairs(family.memberList) do
         if v.fwar then
            f = true
            break  
         end
    end
    if not f then
        local cnt = 0
        for k, v in ipairs(family.memberList) do
            if v.official == FamilyDefine.OFFICIAL_LEADER or v.official == FamilyDefine.OFFICIAL_FU_LEADER then
                cnt = cnt +1
                v.fwar = 1
            end
        end
        for k, v in ipairs(family.memberList) do
            if not v.fwar then
              cnt = cnt + 1
              v.fwar = 1
              if cnt >= 20 then
                break
              end
            end
        end
    end
    signQuery(human)
    Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.FAMILY_WAR_SIGN_OK)
    
    local mm = Msg.gc.GC_BROADCAST
    mm.type = Lang.FAMILY
    mm.msg = Lang.FAMILY_WAR_SIGN_OK_B
    FamilyManager.sendFamily(mm, family)
end

local function changeMembersResult(family)
    for k, v in ipairs(family.memberList) do
        local h = Human.onlineUuid[v.uuid]
        if h then
            h.db.familyWarResult = family.middleFamilyResult 
        end
    end
    FamilyLogicFW.sendFamilyTitle(family)
end

function M2G_FAMILY_WAR_LIST(fd, msg)
    if Config.IS_MIDDLE then return end    
     
    local newStatus = msg.status
    FAMILY_WAR_SIGN_DATA = msg.signData
    FAMILY_WAR_DATA = msg.warData
    
    local family
    if familyWarStatus~= nil and familyWarStatus ~= newStatus and newStatus == TIME_TYPE_READY then --匹配成功
        for k, v in pairs(FAMILY_WAR_SIGN_DATA) do
              family = FamilyManager.findByUuid(v.uuid)
              if family then                  
                  sendFamilyNotify(family, 1)                  
                  sendFamilyMail(family, Lang.FAMILY_WAR_SIGN_TITLE, Lang.FAMILY_WAR_SIGN_MAIL_OK)
                  sendFamilyData(family) 
              end
        end
    end
    if familyWarStatus~= nil and newStatus == TIME_TYPE_ROUND4END and FAMILY_WAR_DATA[1] then
        local rankList = {}
        local rankListByUuid = {}
        for i = 1, 31 do
             local d = FAMILY_WAR_DATA[i]
             if d and not rankListByUuid[d.uuid] then
                rankListByUuid[d.uuid] = 1
                rankList[#rankList + 1] = d
             end
        end
        print("#rankList:", #rankList)
        local first=""
        local second=""
        local third=""
        local four = ""
        for i=1, #rankList do
            if i == 1 then
                first = rankList[i].name
            elseif i == 2 then
                second = rankList[i].name
            elseif i <= 4 then
                third = third..rankList[i].name..","
            elseif i <= 8 then
                four = four..rankList[i].name..","
            end
        end
        local content = string.format(Lang.FAMILY_WAR_FINAL_MAIL_CONTENT, first,second,third,four)
        for i = 1, #rankList do
              family = FamilyManager.findByUuid(rankList[i].uuid)
              if family then
                    family.middleFamilyResult = i
                    changeMembersResult(family)                    
                    sendFamilyMail(family, Lang.FAMILY_WAR_FINAL_MAIL_TITLE, content)
              end
        end
    end
    local f = familyWarStatus
    familyWarStatus = newStatus
    changeFamilyStatus(f)
    
    local data = FAMILY_WAR_DATA[1] or FAMILY_WAR_DATA[100] --霸主或上届霸主
    
    FamilyLogicFW.createFamilyWarWinner(data)
end

function sendFamilyNotify(family, type)
    local msg = Msg.gc.GC_FAMILY_WAR_NOTIFY
    msg.type = type
    msg.copyID = type == 1 and 0 or CopyDefine.COPY_FAMILYWAR_ID
    print("sendFamilyNotify:type:", type)
    FamilyManager.sendFamily(msg, family)
end
function sendFamilyMail(family, title, content, gridlist, memberRewardList)
    for k, v in ipairs(family.memberList) do
        if v.official ~= FamilyDefine.OFFICIAL_LEADER and memberRewardList then
            MailLogicFW.addSystemMessage(v.uuid, title, content, memberRewardList)
        else
            MailLogicFW.addSystemMessage(v.uuid, title, content, gridlist)
        end
    end
end

function changeFamilyStatus(noFirst)
    local flag 
    for uuid, family in pairs(FamilyManager.uuid2Family) do
        flag = nil
        for i = 1, 31 do
            if FAMILY_WAR_DATA[i] and FAMILY_WAR_DATA[i].uuid == uuid then
                family.middleFamilyWarStatus = FAMILY_STATUS_COMBAT
                flag = true
                break
            end
        end
        if not flag then
          for k,v in pairs(FAMILY_WAR_SIGN_DATA) do
            if v.uuid == uuid then
                family.middleFamilyWarStatus = FAMILY_STATUS_SIGN
                flag = true
                break
            end
          end
        end
        
        if not flag then
            if familyWarStatus ~= TIME_TYPE_SIGN and family.middleFamilyWarStatus == FAMILY_STATUS_SIGN then
                family.middleFamilyWarStatus = FAMILY_STATUS_FAIL
                if noFirst then
                  sendFamilyMail(family, Lang.FAMILY_WAR_SIGN_TITLE, Lang.FAMILY_WAR_SIGN_MAIL_FAIL)
                end
            else
                family.middleFamilyWarStatus = FAMILY_STATUS_NOSIGN                
            end
        end
        if familyWarStatus == TIME_TYPE_READY then
            family.middleFamilyResult = 0
            changeMembersResult(family)
        end
        FamilyManager.update(family)
--        print("family:", family.middleFamilyWarStatus)
    end     
     
end

function M2G_FAMILY_WAR_NOTIFY(fd, msg)
    if Config.IS_MIDDLE then return end
    
    local family = FamilyManager.findByUuid(msg.familyUuid1) --胜利方
    if family then
        if msg.type == 0 then
            family.middleFamilyCanEnter = 1            
            sendFamilyNotify(family, msg.round+1)
        elseif msg.type == 1 then
            family.middleFamilyCanEnter = nil    
            local rewardlist = getReward(msg.round, 1)
            local memberRewardlist = msg.round == 4 and getReward(msg.round, 1, true)
            sendFamilyMail(family, Lang.FAMILY_WAR_RESULT_MAIL_TITLE[msg.round], Lang.FAMILY_WAR_RESULT_MAIL_CONTENT_OK,rewardlist, memberRewardlist)           
        end
        FamilyManager.update(family)
    end
    family = FamilyManager.findByUuid(msg.familyUuid2)  --失败方
    if family then
        if msg.type == 0 then
            family.middleFamilyCanEnter = 1
            sendFamilyNotify(family, msg.round+1)
        elseif msg.type == 1 then
            family.middleFamilyCanEnter = nil
            local rewardlist = getReward(msg.round)
            sendFamilyMail(family, Lang.FAMILY_WAR_RESULT_MAIL_TITLE[msg.round], Lang.FAMILY_WAR_RESULT_MAIL_CONTENT_FAIL,rewardlist)
        end
        FamilyManager.update(family)
    end
    
    print("M2G_FAMILY_WAR_NOTIFY:", msg.round, msg.familyUuid1,msg.familyUuid2)
end

------------------跨服逻辑----------------
function G2M_FAMILY_WAR_SIGN(fd, msg)
    if not FAMILY_WAR_SIGN_DATA[msg.familyUuid] then
        FAMILY_WAR_SIGN_DATA[msg.familyUuid] = newData(msg.familyUuid, msg.familyName, msg.svrIndex)  
        insert(FAMILY_WAR_SIGN_DATA[msg.familyUuid])      
    end    
    _G.msg_middle_parse.writebegin(fd)
    _G.msg_middle_parse.writeint(MPacketDefine.M2G_FAMILY_WAR_SIGN)
    _G.msg_middle_parse.writestring(msg.familyUuid)
    _G.msg_middle_parse.writestring(msg.uuid)
    _G.msg_middle_parse.writeend()
end

local cache_data = {}
function syncFamilyWarData(fd)
    for k,v in pairs(cache_data) do
        cache_data[k] = nil
    end
    for k,v in pairs(FAMILY_WAR_SIGN_DATA) do
        cache_data[#cache_data+1] = v
    end
    if fd then
        _G.msg_middle_parse.writebegin(fd)
        _G.msg_middle_parse.writeint(MPacketDefine.M2G_FAMILY_WAR_LIST)
        _G.msg_middle_parse.writeint(familyWarStatus)
        _G.msg_middle_parse.writetable(cache_data)
        _G.msg_middle_parse.writetable(FAMILY_WAR_DATA)
        _G.msg_middle_parse.writeend()
    else
        for fd, v in pairs(MiddleLogic.FD_2_SVNINDEX) do
            _G.msg_middle_parse.writebegin(fd)
            _G.msg_middle_parse.writeint(MPacketDefine.M2G_FAMILY_WAR_LIST)
            _G.msg_middle_parse.writeint(familyWarStatus)
            _G.msg_middle_parse.writetable(cache_data)
            _G.msg_middle_parse.writetable(FAMILY_WAR_DATA)
            _G.msg_middle_parse.writeend()
        end
    end 
end

function notifyFamily(type, round, uuid1,uuid2) -- type = 0 开始，type=1 结果
    for fd, v in pairs(MiddleLogic.FD_2_SVNINDEX) do
            _G.msg_middle_parse.writebegin(fd)
            _G.msg_middle_parse.writeint(MPacketDefine.M2G_FAMILY_WAR_NOTIFY)
            _G.msg_middle_parse.writeint(type)
            _G.msg_middle_parse.writeint(round)
            _G.msg_middle_parse.writestring(uuid1)
            _G.msg_middle_parse.writestring(uuid2)
            _G.msg_middle_parse.writeend()
    end 
end

function G2M_FAMILY_WAR_LIST(fd)
    syncFamilyWarData(fd)
end

function G2M_FAMILY_DATA(fd, msg)
	print("G2M_FAMILY_DATA:", msg.familyUuid, msg.zhandouli, msg.leaderUuid, msg.leaderName)
    for k,v in pairs(FAMILY_WAR_DATA) do
        if v.uuid == msg.familyUuid then
            v.zhandouli = msg.zhandouli
            v.leaderUuid = msg.leaderUuid
            v.leaderName = msg.leaderName
            v.leaderFuUuid = msg.leaderFuUuid
            v.leaderFuName = msg.leaderFuName
            update(v)
        end
    end
    
    for k, v in pairs(FAMILY_WAR_SIGN_DATA) do
        if v.uuid == msg.familyUuid then
            v.zhandouli = msg.zhandouli
            v.leaderUuid = msg.leaderUuid
            v.leaderName = msg.leaderName
            v.leaderFuUuid = msg.leaderFuUuid
            v.leaderFuName = msg.leaderFuName
            update(v)
        end
    end
end

function zhandouliComp(a, b)
    if a.zhandouli == b.zhandouli then
        return a.time < b.time
    else
        return a.zhandouli > b.zhandouli
    end
end
function startWeekWar()  
    local list = {}
    for k,v in pairs(FAMILY_WAR_SIGN_DATA) do
        list[#list+1] = v
    end   
    table.sort(list, zhandouliComp)  
    local r = 16
    local r2 = 20
    local r3 = 24
    local r4 = 28
    local rd = 0
    local l = #list
    if l > 16 then
        l = 16
    end
    for i = 5, l do
        rd = math.random(i, l)
        list[i],list[rd] = list[rd],list[i]
    end
    for i = 1, #list do
        if i <= 16 then
            list[i].rank = 101 --参战
            local d = cloneData(list[i])
              
            rd = i%4
            if rd == 1 then
                d.rank = r
                r = r + 1
            elseif rd == 2 then
                d.rank = r3
                r3 = r3 + 1                
            elseif rd == 3 then
                d.rank = r2
                r2 = r2 + 1
            else
                d.rank = r4
                r4 = r4 + 1
            end
            FAMILY_WAR_DATA[d.rank] = d
            insert(d)
        else
            remove(FAMILY_WAR_SIGN_DATA[list[i].uuid])
            FAMILY_WAR_SIGN_DATA[list[i].uuid] = nil   --落选的
        end
    end
end

function endWeekWar()
    for k,v in pairs(FAMILY_WAR_SIGN_DATA) do
        remove(FAMILY_WAR_SIGN_DATA[k])
        FAMILY_WAR_SIGN_DATA[k] = nil        
    end
    
    if FAMILY_WAR_DATA[1] then
        FAMILY_WAR_DATA[1].rank = 100 --变成上届霸主
        update(FAMILY_WAR_DATA[1])
        if FAMILY_WAR_DATA[100] then
            remove(FAMILY_WAR_DATA[100])
        end
        FAMILY_WAR_DATA[100] = FAMILY_WAR_DATA[1]   
        FAMILY_WAR_DATA[1] = nil
    end
    for k,v in pairs(FAMILY_WAR_DATA) do 
        if k ~= 100 then -- 除去上届霸主，其它全清
            remove(FAMILY_WAR_DATA[k])
            FAMILY_WAR_DATA[k] = nil            
        end
    end
end

function finishApplyRoom(uuid, roomID)
    if not Config.IS_MIDDLE then return end
    local pos = string.find(uuid, "|")
    if not pos then
        return
    end
    local uuid1 = string.sub(uuid, 1, pos-1)
    local uuid2 = string.sub(uuid, pos+1, -1)
    
    print("uuid1:", uuid1, " uuid2:", uuid2, roomID)
    if familyWarStatus == TIME_TYPE_ROUND1 then --第一轮战斗（周五20：00-20：20）
        startRoundWarAfter(1,uuid1, uuid2, roomID)
    elseif familyWarStatus == TIME_TYPE_ROUND2 then --第二轮战斗 （周五21：00-21:20）
        startRoundWarAfter(2,uuid1, uuid2, roomID)
    elseif familyWarStatus == TIME_TYPE_ROUND3 then --第三轮战斗 （周六20：00-20:20）
        startRoundWarAfter(3,uuid1, uuid2, roomID)
    elseif familyWarStatus == TIME_TYPE_ROUND4 then --第四轮战斗 （周六21：00-21：20）
        startRoundWarAfter(4,uuid1, uuid2, roomID)
    end
end

function applyHumanRoom(human)
    if not Config.IS_MIDDLE then return end 
    local roomID = familyCopyRoom[human.familyUuidM]
    if roomID and Copy.roomDatas[CopyDefine.COPY_FAMILYWAR_ID] then
         local data = Copy.roomDatas[CopyDefine.COPY_FAMILYWAR_ID][roomID] 
         if data and data.finishCode == nil then
             local msg = Msg.wl.WL_CROSS_ROOM_APPLY_RESULT
             msg.copyid = CopyDefine.COPY_FAMILYWAR_ID
             msg.roomid = roomID
             Msg.send2logic(msg, human._id) 
             
             print("applyHuman", roomID)
             return
         end
    end 
    --已结束
    MiddleLogic.leave(human)
end


local function getCombatData(winSide, failSide, startRank, endRank)
    local family1
    local family2
    for i = startRank, endRank do
        if FAMILY_WAR_DATA[i] then
            if FAMILY_WAR_DATA[i].uuid == winSide then
                family1 = FAMILY_WAR_DATA[i]
            elseif FAMILY_WAR_DATA[i].uuid == failSide then
                family2 = FAMILY_WAR_DATA[i]
            end
        end
        
        if family1 and family2 then
            break
        end
    end    
    return family1, family2
end


function startRoundWar(round)   --开始一轮（申请房间）
    familyStartTime = os.time()
    familyEndTime = familyStartTime + 1200
    for i = ROUND_RANK[round][1], ROUND_RANK[round][2], 2 do
        if FAMILY_WAR_DATA[i] then
            if FAMILY_WAR_DATA[i+1] then    
                Copy.sendApplyRoom(FAMILY_WAR_DATA[i].uuid.."|"..FAMILY_WAR_DATA[i+1].uuid, CopyDefine.COPY_FAMILYWAR_ID)
                Log.write(Log.LOGID_MIDDLE_FWAR, "startRoundWar1:", round, FAMILY_WAR_DATA[i].uuid.."|"..FAMILY_WAR_DATA[i+1].uuid)                
            else --轮空直接胜利
                update(FAMILY_WAR_DATA[i])
                local new = cloneData(FAMILY_WAR_DATA[i])
                new.rank = math.floor(FAMILY_WAR_DATA[i].rank/2)
                FAMILY_WAR_DATA[new.rank] = new    
                insert(new)            
                if round == 4 then
                     syncFamilyWarData()
                end
                notifyFamily(1, round, FAMILY_WAR_DATA[i].uuid, "")  
                
                Log.write(Log.LOGID_MIDDLE_FWAR, "startRoundWar2:", round, FAMILY_WAR_DATA[i].uuid)                
                              
            end        
        end
    end
end
function startRoundWarAfter(round,uuid1, uuid2, roomID) --真正开始（房间申请好）
    for i = ROUND_RANK[round][1], ROUND_RANK[round][2], 2 do
        if FAMILY_WAR_DATA[i] and FAMILY_WAR_DATA[i].uuid == uuid1 and FAMILY_WAR_DATA[i+1] and FAMILY_WAR_DATA[i+1].uuid == uuid2 then
            familyCopyRoom[uuid1] = roomID
            familyCopyRoom[uuid2] = roomID
            send2logicFamilyWarData(1, FAMILY_WAR_DATA[i], FAMILY_WAR_DATA[i+1], roomID)
            print("..........startRoundWarAfter:", round, uuid1, uuid2)
            notifyFamily(0, round, uuid1, uuid2)            
            Log.write(Log.LOGID_MIDDLE_FWAR, "startRoundWarAfter:", round, uuid1, uuid2, roomID)               
            
            break
        end
    end
end

function endRoundWar(round, type, winSide, failSide)    --结果返回
    print("endRoundWar:", round, type, winSide, failSide)
    local family1,family2 = getCombatData(winSide, failSide, ROUND_RANK[round][1], ROUND_RANK[round][2])
    if not family1 or not family2 then
        assert()
    end 
    if type == 0 then
        if family1.zhandouli < family2.zhandouli then
            family2,family1 = family1,family2
        end
    end
    
    local new = cloneData(family1)
    new.rank = math.floor(family1.rank/2)
    FAMILY_WAR_DATA[new.rank] = new
    insert(new)
    update(family1)
    update(family2)
    syncFamilyWarData()
    notifyFamily(1, round, family1.uuid, family2.uuid)
    
    
    Log.write(Log.LOGID_MIDDLE_FWAR, "endRoundWar:", round, type, winSide, failSide, new.uuid, new.rank)               
    
end

function onTimerMinute()
    if not Config.IS_MIDDLE then
         if not checkMiddleOpen() then 
                return
         end
         if familyWarStatus == TIME_TYPE_SIGN then
              local t = os.time()
              local d = os.date("*t",t)
              if d.wday == 5 and d.hour == 23 and d.min == 59 then                    
                    for uuid, family in pairs(FamilyManager.uuid2Family) do
                        if family.middleFamilyWarStatus == FAMILY_STATUS_SIGN then
                            sendFamilyData(family)
                            print("..........onTimerMinute():", family._id)
                        end    
                    end
                    
              end    
         end  
    else
        if finish4RoundTime and finish4RoundTime + 1200 <= os.time() then --总决赛时，防止L结果返回失败
            finish4RoundTime = nil
            if not FAMILY_WAR_DATA[1] then
              startRoundWarAssert(4)
              syncFamilyWarData()              
              familyCopyRoom = {}
              Log.write(Log.LOGID_MIDDLE_FWAR, "1minute:", familyWarStatus)
            end
        end     
    end
end

function onTimer5Second()
    if not Config.IS_MIDDLE then
        if not FAMILY_WAR_SIGN_DATA then
                if not checkMiddleOpen() then
                    return
                end
                sendFamilyWarDataWQuery()    
        end
        return
    end
    local newStatus = checkTime()
--     print("familyWarStatus:",familyWarStatus, newStatus)
    if newStatus == familyWarStatus then
        return
    end
    --状态切换
    familyWarStatus = newStatus  
    print("newStatus:", newStatus)
    if newStatus == TIME_TYPE_SIGN then  --进入报名
        endWeekWar() 
    elseif newStatus == TIME_TYPE_READY then --准备时间（周五20：00前）
        startWeekWar()
    elseif newStatus == TIME_TYPE_ROUND1 then --第一轮战斗（周五20：00-20：20）
        startRoundWar(1)
    elseif newStatus == TIME_TYPE_ROUND1END then --第一轮战斗结束（周五20：20-20：59）
        send2logicFamilyWarData(0)
    elseif newStatus == TIME_TYPE_ROUND2 then --第二轮战斗 （周五21：00-21:20）
        startRoundWarAssert(1) --这里先检查下上一轮是否成功
        startRoundWar(2)
    elseif newStatus == TIME_TYPE_ROUND2END then --第二轮战斗结束（周六20：20 到周一）
        send2logicFamilyWarData(0)
    elseif newStatus == TIME_TYPE_ROUND3 then --第三轮战斗 （周六20：00-20:20）
        startRoundWarAssert(2) --这里先检查下上一轮是否成功
        startRoundWar(3)
    elseif newStatus == TIME_TYPE_ROUND3END then--第三轮战斗结束（周六20：20-20：59）
        send2logicFamilyWarData(0)
    elseif newStatus == TIME_TYPE_ROUND4 then --第四轮战斗开始（周六21:00-21:20)
        startRoundWarAssert(3) --这里先检查下上一轮是否成功
        startRoundWar(4)
    elseif newStatus == TIME_TYPE_ROUND4END then --第四轮战斗结束(周六21:20-周一)
        send2logicFamilyWarData(0)
        finish4RoundTime = os.time()
    end
    syncFamilyWarData()
    saveWarStatus()
    
    Log.write(Log.LOGID_MIDDLE_FWAR, "timer:", familyWarStatus)
end

function startRoundWarAssert(round)   --异常处理一轮
    for i = ROUND_RANK[round][1], ROUND_RANK[round][2], 2 do
        if FAMILY_WAR_DATA[i] then
            local r = math.floor(FAMILY_WAR_DATA[i].rank/2)
            if not FAMILY_WAR_DATA[r] then
                if FAMILY_WAR_DATA[i+1] then    --轮空直接胜利
                    local family1 = FAMILY_WAR_DATA[i]
                    local family2 = FAMILY_WAR_DATA[i+1]
                    if family1.zhandouli < family2.zhandouli then
                        family2,family1 = family1,family2
                    end
                    local new = cloneData(family1)
                    new.rank = math.floor(family1.rank/2)
                    FAMILY_WAR_DATA[new.rank] = new    
                    insert(new)            
               
                else 
                    update(FAMILY_WAR_DATA[i])
                    local new = cloneData(FAMILY_WAR_DATA[i])
                    new.rank = math.floor(FAMILY_WAR_DATA[i].rank/2)
                    FAMILY_WAR_DATA[new.rank] = new    
                    insert(new)                           
                end
             end        
        end
    end
end

function AssertFix_TIME_TYPE_SIGN() 
    endWeekWar()  
end
function AssertFix_TIME_TYPE_READY() 
    startWeekWar() 
end
function AssertFix_TIME_TYPE_ROUND1() 
    startRoundWarAssert(1)  
end
function AssertFix_TIME_TYPE_ROUND1END()  
    startRoundWarAssert(1)
end
function AssertFix_TIME_TYPE_ROUND2() 
    startRoundWarAssert(2)  
end
function AssertFix_TIME_TYPE_ROUND2END()
    startRoundWarAssert(2)  
end
function AssertFix_TIME_TYPE_ROUND3() 
    startRoundWarAssert(3)
end
function AssertFix_TIME_TYPE_ROUND3END()
    startRoundWarAssert(3)
end
function AssertFix_TIME_TYPE_ROUND4() 
    startRoundWarAssert(4)
end
function AssertFix_TIME_TYPE_ROUND4END()
    startRoundWarAssert(4)
end

AssertFix[TIME_TYPE_SIGN] = AssertFix_TIME_TYPE_SIGN
AssertFix[TIME_TYPE_READY] = AssertFix_TIME_TYPE_READY
AssertFix[TIME_TYPE_ROUND1] = AssertFix_TIME_TYPE_ROUND1
AssertFix[TIME_TYPE_ROUND1END] = AssertFix_TIME_TYPE_ROUND1END
AssertFix[TIME_TYPE_ROUND2] = AssertFix_TIME_TYPE_ROUND2
AssertFix[TIME_TYPE_ROUND2END] = AssertFix_TIME_TYPE_ROUND2END
AssertFix[TIME_TYPE_ROUND3] = AssertFix_TIME_TYPE_ROUND3
AssertFix[TIME_TYPE_ROUND3END] = AssertFix_TIME_TYPE_ROUND3END
AssertFix[TIME_TYPE_ROUND4] = AssertFix_TIME_TYPE_ROUND4
AssertFix[TIME_TYPE_ROUND4END] = AssertFix_TIME_TYPE_ROUND4END

function send2logicFamilyWarData(type, family1, family2, roomID)
    local data
    if type == 1 then
      data = {
        type = type,
        roomID = roomID,
        startTime = familyStartTime,
        endTime = familyEndTime,
        family = {
            {familyUuid=family1.uuid, familyName=family1.name, leaderUuid = family1.leaderUuid, leaderName = family1.leaderName, leaderFuUuid =family1.leaderFuUuid,zhandouli = family1.zhandouli},
            {familyUuid=family2.uuid, familyName=family2.name, leaderUuid = family2.leaderUuid, leaderName = family2.leaderName, leaderFuUuid =family2.leaderFuUuid,zhandouli = family2.zhandouli}   
        },
      }
    else
      data = {
        type = type
      }    
    end
    InnerDataManagerFW.Send2LInnerData(nil, InnerDefine.INNERDATA_TYPE_MIDDLE_FAMILY_WAR, data)
end
function onFamilyWarResult(oHuman, type, data)
    if familyWarStatus == TIME_TYPE_ROUND1 or familyWarStatus == TIME_TYPE_ROUND1END then    
       endRoundWar(1,data.data.type, data.data.winside, data.data.failside) 
    elseif familyWarStatus == TIME_TYPE_ROUND2 or familyWarStatus == TIME_TYPE_ROUND2END then
       endRoundWar(2, data.data.type, data.data.winside, data.data.failside) 
    elseif familyWarStatus == TIME_TYPE_ROUND3 or familyWarStatus == TIME_TYPE_ROUND3END then
       endRoundWar(3, data.data.type, data.data.winside, data.data.failside) 
    elseif familyWarStatus == TIME_TYPE_ROUND4 or familyWarStatus == TIME_TYPE_ROUND4END then
       endRoundWar(4, data.data.type, data.data.winside, data.data.failside) 
    end
    
    for k,v in pairs(familyCopyRoom) do
        if v == data.roomID then
            familyCopyRoom[k] = nil
        end
    end
end
InnerDataManagerFW.Register(InnerDefine.INNERDATA_TYPE_MIDDLE_FWAR_RESULT, onFamilyWarResult)

